﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public partial class DicClass : ICreator { }



	/// <summary>
	/// DicClasses 类。
	/// </summary>
	public static partial class DicClasses
	{
		public const string INFO_TYPE = "DicClass";


		#region GetIdentifier
		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="classCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		public static int? GetIdentifier(int? siteId, string classCode)
		{
			string key = siteId + "-" + classCode;
			Dictionary<string, int?> ids = GenericCacheContainer.Instance.DicClassIdByCodeDictionary;
			if (ids.ContainsKey(key))
				return ids[key];

			lock (ids)
			{
				if (!ids.ContainsKey(key))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					int? value = dc.DicClasses.GetIdentifier(siteId, classCode);
					try
					{
						ids[key] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						ids.Clear();
						ids[key] = value;
					}
				}
			}
			return ids[key];
		}

		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="classCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		internal static int? GetIdentifier(this System.Data.Linq.Table<DicClass> o, int? siteId, string classCode)
		{
			var q = from p in o
					where p.ClassCode == classCode
					select p;
			if (siteId.HasValue)
				q = q.Where(p => p.SiteId == siteId.Value);
			else
				q = q.Where(p => p.SiteId == null);
			var q1 = q.Select(p => (int?)p.ClassId);
			
			return q1.SingleOrDefault();
		}
		#endregion



		#region GetItem
		/// <summary>
		/// 根据标识获取指定的类别。
		/// </summary>
		/// <param name="o">类别集合。</param>
		/// <param name="id">获取的标识。</param>
		/// <returns>获取的类别。</returns>
		public static DicClass GetItem(this System.Data.Linq.Table<DicClass> o, int id)
		{
			return o.SingleOrDefault(p => p.ClassId == id);
		}

		public static DicClass GetItem(int id)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.DicClasses.GetItem(id);
		}



		/// <summary>
		/// 根据类别代码获取指定的类别。
		/// </summary>
		/// <param name="o">类别集合。</param>
		/// <param name="code">获取的代码。</param>
		/// <returns>获取的类别。</returns>
		public static DicClass GetItem(this System.Data.Linq.Table<DicClass> o, int? siteId, string code)
		{
			if(siteId.HasValue)
				return o.SingleOrDefault(p => p.SiteId == siteId && p.ClassCode == code);
			else
				return o.SingleOrDefault(p => p.SiteId == null && p.ClassCode == code);
		}

		public static DicClass GetItem(int? siteId, string code)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.DicClasses.GetItem(siteId, code);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的类别标识是否已经存在。
		/// </summary>
		/// <param name="o">类别集合。</param>
		/// <param name="id">验证的类别标识。</param>
		/// <returns>布尔值表示指定的类别标识是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<DicClass> o, int id)
		{
			return o.Any(p => p.ClassId == id);
		}

		public static bool Exists(int id)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.DicClasses.Exists(id);
		}

		/// <summary>
		/// 验证指定的类别代码是否已经存在。
		/// </summary>
		/// <param name="o">类别集合。</param>
		/// <param name="code">验证的类别代码。</param>
		/// <returns>布尔值表示指定的类别代码是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<DicClass> o, int? siteId, string code)
		{
			if (siteId.HasValue)
				return o.Any(p => p.SiteId == siteId && p.ClassCode == code);
			else
				return o.Any(p => p.SiteId == null && p.ClassCode == code);
		}

		public static bool Exists(int? siteId, string code)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.DicClasses.Exists(siteId, code);
		}
		#endregion
	}



	/// <summary>
	/// DicClasses 类操作部分。
	/// </summary>
	public static partial class DicClasses
	{
		#region Register
		internal static DicClass Register(DicClass registerDicClass)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			DicClass dicClass = dc.DicClasses.GetItem(registerDicClass.ClassId);
			if (dicClass == null)
			{
				dicClass = registerDicClass.ToNewEntity<DicClass>();
				dicClass.CreatorId = Users.CurrentUserId;
				dicClass.CreationDate = DateTime.Now;
				dc.DicClasses.InsertOnSubmit(dicClass);
				dc.SubmitChanges();
			}
			else
			{
				if (dicClass.SiteId != registerDicClass.SiteId || dicClass.ClassCode != registerDicClass.ClassCode || dicClass.ClassName != registerDicClass.ClassName || dicClass.Memo != registerDicClass.Memo)
				{
					// 修正数据，以确保数据的正确性
					dicClass.SiteId = registerDicClass.SiteId;
					dicClass.ClassCode = registerDicClass.ClassCode;
					dicClass.ClassName = registerDicClass.ClassName;
					dicClass.Memo = registerDicClass.Memo;

					try
					{
						dc.SubmitChanges(ConflictMode.ContinueOnConflict);
					}
					catch (ChangeConflictException e)
					{
						foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
							occ.Resolve(RefreshMode.KeepCurrentValues);
					}
				}
			}

			// 返回只读数据。
			return registerDicClass.FillByEntity(dicClass);
		}
		#endregion




		#region Insert
		/// <summary>
		/// 添加字典类别。
		/// </summary>
		/// <param name="insertedDicClass">添加的字典类别信息。</param>
		/// <returns>添加的字典类别。</returns>
		public static DicClass Insert(DicClass insertedDicClass)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			DicClass dicClass = insertedDicClass.ToNewEntity<DicClass>();
			dicClass.CreatorId = Users.CurrentUserId;
			dicClass.CreationDate = DateTime.Now;

			GetInsertRight(dc, dicClass, true);	// 权限验证

			if (dc.DicClasses.Exists(dicClass.ClassId))
				throw new ObjectExistsException(Res.DicClasses_ExistsClassId);
			if (dc.DicClasses.Exists(dicClass.SiteId, dicClass.ClassCode))
				throw new ObjectExistsException(Res.DicClasses_ExistsClassCode);

			dc.DicClasses.InsertOnSubmit(dicClass);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Insert, INFO_TYPE, dicClass.ClassId.ToString(), PermissionCode.Insert.ToString(), dicClass.ClassName);

			// 返回只读数据
			return insertedDicClass.FillByEntity(dicClass);
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedExcludeColumns = typeof(DicClass).GetEntityColumnNames(new string[] {
				"ClassId",
				"ClassCode",
				"CreationDate",
				"CreatorId",
				"SiteId"
			}, true);

		/// <summary>
		/// 修改字典类别。
		/// </summary>
		/// <param name="updatedDicClass">修改的字典类别。</param>
		/// <returns>修改的字典类别。</returns>
		public static DicClass Update(DicClass updatedDicClass)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			DicClass dicClass = dc.DicClasses.GetItem(updatedDicClass.ClassId);
			if (dicClass == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, dicClass, true);	// 权限验证

			dicClass.FillByEntity(updatedDicClass, EntityColumnsSetType.Exclude, _updatedExcludeColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Update, INFO_TYPE, dicClass.ClassId.ToString(), PermissionCode.Update.ToString(), dicClass.ClassName);

			// 返回只读数据
			return updatedDicClass.FillByEntity(dicClass);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除类别。
		/// </summary>
		/// <param name="id">删除的类别标识。</param>
		public static void Delete(int id)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			DicClass dicClass = dc.DicClasses.GetItem(id);
			if (dicClass == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, dicClass, true);	// 权限验证

			Delete(dc, dicClass);
			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, dicClass.ClassId.ToString(), PermissionCode.Delete.ToString(), dicClass.ClassName);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, DicClass dicClass)
		{
			Dictionaries.DeleteByParent(dc, dicClass);	// 删除关联数据
			dc.DicClasses.DeleteOnSubmit(dicClass);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// DicClasses 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class DicClasses
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="dicClass">添加的类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加类别的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, DicClass dicClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Insert;
			bool b = dc.AccessController.GetUserIsHasPermission<DicClass>(userName, dicClass, ResourceId, permissionCode, dicClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, dicClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有添加类别的权限。
		/// </summary>
		/// <param name="dicClass">添加的类别对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加类别的权限。</returns>
		public static bool GetInsertRight(DicClass dicClass, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), dicClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加类别的权限。
		/// </summary>
		/// <param name="dicClass">添加的类别对象。</param>
		/// <returns>布尔值表示当前用户是否有添加类别的权限。</returns>
		public static bool GetInsertRight(DicClass dicClass)
		{
			return GetInsertRight(dicClass, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="dicClass">更新的类别。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新类别的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, DicClass dicClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Update;
			bool b = dc.AccessController.GetUserIsHasPermission<DicClass>(userName, dicClass, ResourceId, permissionCode, dicClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, dicClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有更新类别的权限。
		/// </summary>
		/// <param name="dicClass">更新的类别。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新类别的权限。</returns>
		public static bool GetUpdateRight(DicClass dicClass, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), dicClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新类别的权限。
		/// </summary>
		/// <param name="dicClass">更新的类别。</param>
		/// <returns>布尔值表示当前用户是否有更新类别的权限。</returns>
		public static bool GetUpdateRight(DicClass dicClass)
		{
			return GetUpdateRight(dicClass, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除类别的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="dicClass">删除的类别。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除类别的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, DicClass dicClass, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Delete;
			bool b = dc.AccessController.GetUserIsHasPermission<DicClass>(userName, dicClass, ResourceId, permissionCode, dicClass.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, dicClass, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除类别的权限。
		/// </summary>
		/// <param name="dicClass">删除的类别。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除类别的权限。</returns>
		public static bool GetDeleteRight(DicClass dicClass, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), dicClass, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除类别的权限。
		/// </summary>
		/// <param name="dicClass">删除的类别。</param>
		/// <returns>布尔值表示当前用户是否有删除类别的权限。</returns>
		public static bool GetDeleteRight(DicClass dicClass)
		{
			return GetDeleteRight(dicClass, false);
		}
		#endregion
	}




	/// <summary>
	/// DicClasses 类后台管理部分。
	/// </summary>
	public static partial class DicClasses
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, DicClasses.ResourceId, (int)DicClasses.PermissionCode.Update, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, DicClasses.ResourceId, (int)DicClasses.PermissionCode.Update, siteId);
		}



		public static PaginationInfo<List<DicClass>> GetPaginationManageList(int? siteId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.DicClasses
					select p;

			if (siteId.HasValue)
				q = q.Where(p => p.SiteId == siteId.Value);
			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.ClassName.Contains(keyword));

			PaginationInfo<List<DicClass>> pageInfo = new PaginationInfo<List<DicClass>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
	}
}